<template>
  <div class="chatBox">
    <span>AI源：</span>
    <el-select v-model="aiModel" placeholder="请选择">
      <el-option
        v-for="item in aiModelList"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      />
    </el-select>
    <div class="chat">
      <div class="right">
        <div ref="messageBox" class="oner">
          <ul :key="recordKey">
            <li
              v-for="(item, index) in historyMessage"
              :key="index"
              :class="[index % 2 == 0 ? 'user' : 'api']"
            >
              <div v-if="index % 2 == 0" class="message-content">
                {{ item.message }}
              </div>
              <div
                v-if="index % 2 != 0 && item.type == 'success'"
                class="message-success_content"
              >
                <div style="margin-right: 15px">
                  <img :src="item.logo" alt="" class="aiLogo">
                </div>
                <Markdown
                  ref="mark"
                  :source="item.message"
                  :loading="loading"
                  @applySink="applySink"
                />
              </div>
              <div
                v-if="index % 2 != 0 && item.type == 'error'"
                class="message-success_content"
              >
                <div style="margin-right: 15px">
                  <img :src="item.logo" alt="" class="aiLogo">
                </div>
                <p style="color: red; margin: 0">
                  {{ item.message }}
                </p>
              </div>
            </li>
            <li v-if="loading">
              <div>
                <img
                  style="height: 60px"
                  src="@/assets/ai_img/icon/loading.gif"
                  alt="生成中"
                >
              </div>
            </li>
          </ul>
        </div>
      </div>
    </div>
    <div class="chat-input-container" tabindex="0" data-testid="chat_input">
      <div class="chat-input grid-container">
        <div class="grid-input-area">
          <div
            class="container-AilALM flow-xs54Ev input custom-scrollbar-xZDNG1 semi-input-textarea-wrapper"
          >
            <textarea
              id="chatMessages"
              ref="inputRef"
              v-model="messageValue"
              dir="ltr"
              rows="1"
              autocomplete="off"
              data-testid="chat_input_input"
              cols="20"
              class="semi-input-textarea semi-input-textarea-autosize"
              placeholder="转换要求"
              @keydown="handleKeydown"
              @input="handleInputMessage"
            />
          </div>
          <div class="line" />
          <button
            id="flow-end-msg-send"
            aria-disabled="false"
            aria-label="发送"
            data-testid="chat_input_send_button"
            aria-describedby="9du7ipz"
            tabindex="0"
            data-popupid="9du7ipz"
            class="semi-button semi-button-primary send-btn-fDrkYV semi-button-with-icon semi-button-with-icon-only"
            type="button"
            @click="handleSendMessage"
          >
            <span
              class="semi-button-content"
            ><span
              role="img"
              class="semi-icon semi-icon-default"
            ><svg
              xmlns="http://www.w3.org/2000/svg"
              width=".7em"
              height=".7em"
              fill="currentColor"
              viewBox="0 0 28 28"
              :style="{
                color: messageValue.length == 0 ? '#aaa' : '#06f',
              }"
            >
              <path
                d="M14.007 28q-2.881 0-5.418-1.11a14.3 14.3 0 0 1-4.453-3.026 14.5 14.5 0 0 1-3.04-4.453Q0 16.875 0 13.993q0-2.868 1.095-5.404Q2.191 6.053 4.121 4.12A14.5 14.5 0 0 1 8.59 1.095Q11.124 0 13.993 0t5.404 1.095q2.536 1.096 4.467 3.026A14.2 14.2 0 0 1 26.89 8.59Q28 11.124 28 13.993q0 2.881-1.095 5.418a14.3 14.3 0 0 1-3.027 4.453 14.2 14.2 0 0 1-4.467 3.026Q16.876 28 14.007 28m.015-6.917q.518 0 .835-.317.332-.332.332-.836v-6.816l-.13-2.969 1.37 1.672 1.599 1.643q.316.33.807.331.475 0 .792-.303a.99.99 0 0 0 .332-.763q0-.475-.332-.807L14.944 7.22q-.433-.447-.922-.447-.476 0-.908.447L8.43 11.918q-.317.317-.317.807 0 .461.317.763.318.303.778.303.49 0 .807-.331l1.629-1.658 1.326-1.642-.116 2.954v6.816q0 .504.332.836.331.317.836.317"
              /></svg></span></span>
          </button>
        </div>
      </div>
    </div>
    <div :class="{ fn_bottom: true, bottomHidden: bottomHidden }">
      <div class="svg">
        <svg
          t="1731571200583"
          class="icon"
          viewBox="0 0 1024 1024"
          version="1.1"
          xmlns="http://www.w3.org/2000/svg"
          p-id="8607"
          width="25"
          height="25"
          @click="bottomHidden = true"
        >
          <path
            d="M722.773333 381.44a64 64 0 0 1 90.453334 90.453333l-252.970667 253.013334a68.266667 68.266667 0 0 1-96.512 0l-253.013333-253.013334a64 64 0 0 1 90.538666-90.453333L512 592.128l210.773333-210.773333z"
            fill="#eee"
            p-id="8608"
          />
        </svg>
      </div>
      <div class="fn_bottom-main">
        <div class="fn_bottom-main-item" @click="handleSuccess">
          <svg
            t="1731983736761"
            class="icon"
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="41864"
            width="20"
            height="20"
          >
            <path
              d="M512 1024C230.4 1024 0 793.6 0 512S230.4 0 512 0s512 230.4 512 512-230.4 512-512 512z m0-938.666667C277.333333 85.333333 85.333333 277.333333 85.333333 512s192 426.666667 426.666667 426.666667 426.666667-192 426.666667-426.666667S746.666667 85.333333 512 85.333333z"
              p-id="41865"
              fill="#ffffff"
            />
            <path
              d="M708.266667 375.466667c-17.066667-17.066667-44.8-17.066667-59.733334 0l-181.333333 181.333333-91.733333-91.733333c-14.933333-14.933333-40.533333-14.933333-55.466667 0l-6.4 4.266666c-14.933333 14.933333-14.933333 40.533333 0 55.466667l125.866667 125.866667c14.933333 14.933333 40.533333 14.933333 55.466666 0l4.266667-4.266667 209.066667-209.066667c17.066667-17.066667 17.066667-44.8 0-61.866666z"
              p-id="41866"
              fill="#ffffff"
            />
          </svg>
          <p>成功并保存</p>
        </div>
        <div class="fn_bottom-main-item" @click="handleContrastDdl = true">
          <svg
            t="1731658473152"
            class="icon"
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="27269"
            width="20"
            height="20"
          >
            <path
              d="M493.856 125.568c10.732 0 21.016 4.304 28.56 11.948l249.416 252.7a40.216 40.216 0 0 1 11.588 28.248V887.8c0 22.2-17.976 40.196-40.152 40.196H228.152C205.976 927.996 188 910 188 887.8V165.76c0-22.2 17.976-40.192 40.152-40.192h265.704zM710.808 96l213.432 213.656a40.212 40.212 0 0 1 11.74 27.092l0.02 1.324V928h-80.304V354.72l-201.676-201.88L710.808 96z m-249.864 109.96h-192.64V847.6H703.12v-384.42h-202.012c-21.804 0-39.544-17.388-40.14-39.068l-0.016-1.124V205.96h-0.008z m190.672 176.84l-110.364-111.824V382.8h110.36z"
              p-id="27270"
              fill="#ffffff"
            />
            <path
              d="M364 552h224v80H364zM364 732h224v80H364z"
              p-id="27271"
              fill="#ffffff"
            />
            <path d="M516 480v224h-80v-224z" p-id="27272" fill="#ffffff" />
          </svg>
          <p>ddl对比</p>
        </div>
        <div class="fn_bottom-main-item" @click="handleSqlTask">
          <svg
            t="1731651662494"
            class="icon"
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="18837"
            width="20"
            height="20"
          >
            <path
              d="M512 128a382.6 382.6 0 1 1-149.45 30.15A381.54 381.54 0 0 1 512 128m0-64C264.58 64 64 264.58 64 512s200.58 448 448 448 448-200.58 448-448S759.42 64 512 64z"
              p-id="18838"
              fill="#ffffff"
            />
            <path
              d="M352 256v512l448-256-448-256z"
              p-id="18839"
              fill="#ffffff"
            />
          </svg>
          <p>执行</p>
        </div>
        <div class="fn_bottom-main-item" @click="previewErrorTipsDialog = true">
          <svg
            t="1731651776039"
            class="icon"
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="19950"
            width="20"
            height="20"
          >
            <path
              d="M953.38 512c0-243.767-197.613-441.38-441.38-441.38S70.62 268.234 70.62 512 268.234 953.38 512 953.38 953.38 755.766 953.38 512zM512 462.064L362.213 312.276c-13.889-13.888-36.169-13.811-49.958-0.021-13.886 13.885-13.78 36.156 0.021 49.958L462.064 512 312.276 661.787c-13.888 13.889-13.811 36.169-0.021 49.958 13.885 13.886 36.156 13.78 49.958-0.021L512 561.936l149.787 149.788c13.889 13.888 36.169 13.811 49.958 0.021 13.886-13.885 13.78-36.156-0.021-49.958L561.936 512l149.788-149.787c13.888-13.889 13.811-36.169 0.021-49.958-13.885-13.886-36.156-13.78-49.958 0.021L512 462.064zM0 512C0 229.23 229.23 0 512 0s512 229.23 512 512-229.23 512-512 512S0 794.77 0 512z"
              p-id="19951"
              fill="#ffffff"
            />
          </svg>
          <p>错误信息</p>
        </div>
        <div
          class="fn_bottom-main-item"
          @click="previewErrorStackTipsDialog = true"
        >
          <svg
            t="1731651820923"
            class="icon"
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="23274"
            width="20"
            height="20"
          >
            <path
              d="M67.584 140.288h744.96c3.072 0 3.584-4.096 1.024-4.608L708.096 102.4H195.584l-128.512 32.768c-3.072 1.024-2.56 5.12 0.512 5.12zM90.112 366.08h699.904c14.336 0 26.112-11.264 26.112-24.576V178.688c0-13.824-11.776-24.576-26.112-24.576H90.112c-14.336 0-26.112 11.264-26.112 24.576v162.816c-0.512 13.824 11.264 24.576 26.112 24.576zM662.016 230.4c17.408 0 31.744 13.312 31.744 29.696s-14.336 29.696-31.744 29.696c-17.408 0-31.744-13.312-31.744-29.696 0-16.384 14.336-29.696 31.744-29.696z m-99.84 0c17.408 0 31.744 13.312 31.744 29.696s-14.336 29.696-31.744 29.696c-17.408 0-31.744-13.312-31.744-29.696 0-16.384 14.336-29.696 31.744-29.696z m-377.344 2.048h176.64v55.808H184.832V232.448zM568.32 772.608c-2.048 0.512-3.584 0.512-5.632 0.512-17.408 0-31.744-13.312-31.744-29.696s14.336-29.696 31.744-29.696c1.024-26.624 6.144-52.224 15.36-76.288H90.112c-14.336 0-26.112 11.264-26.112 24.576v162.816c0 13.824 11.776 24.576 26.112 24.576h511.488c-15.36-23.04-26.624-48.64-33.28-76.8z m-206.848-1.024H184.832v-55.808h176.64v55.808zM661.504 531.456c-17.408-0.512-31.232-13.824-31.232-29.696 0-16.384 14.336-29.696 31.744-29.696 17.408 0 31.744 13.312 31.744 29.696 0 4.608-1.024 8.704-3.072 12.288 30.72-15.36 65.024-23.552 101.888-23.552 8.192 0 15.872 0.512 23.552 1.024V420.352c0-13.824-11.776-24.576-26.112-24.576H90.112c-14.336 0-26.112 11.264-26.112 24.576v162.816c0 13.824 11.776 24.576 26.112 24.576h501.76c17.408-30.208 40.96-56.32 69.632-76.288z m-300.032-1.536H184.832v-56.32h176.64v56.32z m169.472-28.16c0-16.384 14.336-29.696 31.744-29.696 17.408 0 31.744 13.312 31.744 29.696 0 16.384-14.336 29.696-31.744 29.696-17.92 0-31.744-13.312-31.744-29.696z"
              p-id="23275"
              fill="#ffffff"
            />
            <path
              d="M792.576 517.12c-113.152 0-204.8 91.648-204.8 204.8s91.648 204.8 204.8 204.8 204.8-91.648 204.8-204.8c0-112.64-91.648-204.8-204.8-204.8z m75.776 275.456c-8.192 8.192-21.504 8.704-29.696 1.024l-45.056-42.496-43.008 45.568c-8.192 8.192-21.504 8.704-29.696 1.024s-8.704-21.504-1.024-29.696l42.496-45.056-45.056-42.496c-8.192-8.192-8.704-21.504-1.024-29.696s21.504-8.704 29.696-1.024l45.056 42.496 42.496-45.056c8.192-8.192 21.504-8.704 29.696-1.024 8.192 7.168 8.192 20.992 1.536 28.672l-42.496 45.056 45.056 42.496c8.192 8.192 8.704 22.016 1.024 30.208z"
              fill="#ffffff"
              p-id="23276"
            />
          </svg>
          <p>堆栈错误</p>
        </div>
      </div>
    </div>
    <div :class="{ top_display: bottomHidden }" style="display: none">
      <svg
        t="1731639754244"
        class="icon"
        viewBox="0 0 1024 1024"
        version="1.1"
        xmlns="http://www.w3.org/2000/svg"
        p-id="15352"
        width="25"
        height="25"
        @click="bottomHidden = false"
      >
        <path
          d="M838.9 640.5L536.2 337.8c-6.4-6.4-14.8-9.5-23.2-9.4-8.4-0.1-16.8 3-23.2 9.4L187.1 640.5c-12.6 12.6-12.6 33 0 45.6 12.6 12.6 33 12.6 45.6 0L513 405.9l280.3 280.3c12.6 12.6 33 12.6 45.6 0 12.6-12.6 12.6-33.1 0-45.7z"
          fill="#eee"
          p-id="15353"
        />
      </svg>
    </div>
    <el-dialog
      title="错误信息"
      width="800px"
      :visible.sync="previewErrorTipsDialog"
    >
      <div>
        <p
          style="white-space: pre-wrap; max-height: 480px"
          class="errMessageTips"
        >
          {{ errorMessage }}
        </p>
      </div>
    </el-dialog>
    <el-dialog
      title="堆栈错误信息"
      width="800px"
      :visible.sync="previewErrorStackTipsDialog"
    >
      <div>
        <p
          style="white-space: pre-wrap; max-height: 480px"
          class="errMessageTips"
        >
          {{ errorStackMessage }}
        </p>
      </div>
    </el-dialog>
    <el-dialog title="ddl对比" width="1100px" :visible.sync="handleContrastDdl">
      <div class="contrastBox">
        <div style="width: 45%">
          <CodeEditor
            title="源ddl"
            :editor-hight="400"
            :code-data="contrastDdl.sourceDdl"
            :value-font-size="12"
          />
        </div>
        <div class="Divider" />
        <div style="width: 45%">
          <CodeEditor
            :key="sinkKey"
            title="目标ddl"
            :editor-hight="400"
            :code-data="contrastDdl.sinkDdl"
            :value-font-size="12"
          />
        </div>
      </div>
    </el-dialog>
    <div class="grammar">
      <el-checkbox
        v-model="grammarChecked"
        @change="handleCheckbox"
      ><span class="label">语法兼容转换</span>
        <el-select
          v-if="grammarChecked"
          v-model="grammarCheckedValue"
          style="width: 100%"
          placeholder="请选择语法兼容库"
        >
          <el-option
            v-for="item in dict.type.grammar_compatible_conversion"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-checkbox>
      <span class="a" @click="previewTipsDialog = true">查看提示词</span>
    </div>
    <div class="tips">
      <p class="label">
        提示语句
        <span
          class="changeTips"
          @click="getKeyword"
        >换一批
          <svg
            t="1730871261743"
            class="icon"
            viewBox="0 0 1024 1024"
            version="1.1"
            xmlns="http://www.w3.org/2000/svg"
            p-id="4445"
            width="12"
            height="12"
          >
            <path
              d="M949.252087 430.532547c-9.240455-7.446599-22.75526-5.965875-30.169113 3.328815l-36.743856 46.075385c-1.208525-17.817808-3.606131-35.751249-7.338129-53.722552C829.114916 204.421786 613.312942 62.124919 393.013537 108.309798 172.691619 154.50798 31.294239 371.70165 77.179288 593.470523c45.88505 221.791385 261.688048 364.101555 482.009965 317.880861 80.081896-16.785292 148.922774-56.816007 202.800869-110.918205 0.199545-0.198521 0.401136-0.355087 0.602727-0.578168 0.956791-0.979304 1.290389-2.113127 2.248204-3.115967 1.578961-2.670829 2.714831-5.855358 2.714831-9.171893 0-9.82067-7.92346-17.790178-17.675568-17.790178-5.254677 0-9.842159 2.405793-13.093203 6.078439l-0.130983-0.11154c-48.916083 49.047066-111.676475 85.202521-184.344518 100.432387-199.506846 41.833781-394.937864-87.050612-436.482049-287.880593-41.566698-200.809515 86.493933-397.531945 285.999756-439.364703 199.506846-41.822524 394.937864 87.073124 436.480003 287.880593 3.207042 15.446807 5.425569 30.855752 6.712889 46.165436l-44.603871-36.034704c-9.262968-7.470135-22.753213-5.966898-30.169113 3.317559-7.435343 9.317203-5.944386 22.898523 3.297093 30.390147 0.045025 0.022513 0.045025 0.022513 0.090051 0.022513l82.132602 66.39006c0.020466 0 0.065492 0.044002 0.086981 0.066515 4.692882 3.793396 10.480702 5.266957 16.016789 4.590552 5.539156-0.555655 10.861372-3.25616 14.617929-7.964392 0.021489-0.021489 0.045025-0.066515 0.045025-0.066515l65.944921-82.71998c0.021489-0.021489 0.021489-0.021489 0.065492-0.045025C959.95894 451.606515 958.492542 438.012915 949.252087 430.532547z"
              fill="#555555"
              p-id="4446"
            />
          </svg>
        </span>
      </p>
      <div class="tips-content">
        <el-checkbox-group
          v-model="checkList"
          style="display: flex; flex-wrap: wrap"
        >
          <el-checkbox
            v-for="item in keywordList"
            :key="item"
            :label="item"
            class="tips-item"
          />
        </el-checkbox-group>
      </div>
    </div>

    <el-dialog
      title="提示词预览"
      width="800px"
      :visible.sync="previewTipsDialog"
    >
      <div>
        <p style="white-space: pre-wrap" class="message-content">
          "{{ getMessageValue() }}
        </p>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { doubao, tongyi, wenxin, chatgpt, zhipu } from '@/assets/ai_img/index'
import Markdown from '@/components/marckdown'
import CodeEditor from '@/components/CodeEditor/index.vue'
import { sqlTaskExecuteSql } from '@/api/console/executeSql'
import { dataReportObjectEdit } from '@/api/console/dataTaskLog'

import {
  sendAiMessage,
  getKeyword,
  convertSqlPush,
  getAiList
} from '@/api/console/belfAi'
export default {
  name: 'MigrationReportAiChat',
  components: {
    Markdown,
    CodeEditor
  },
  props: ['executeSqlData', 'databaseInfo', 'taskType', 'sinkDdl'],
  dicts: ['grammar_compatible_conversion'],
  data() {
    return {
      executeErrorMessage: null,
      handleContrastDdl: false,
      historyMessage: [],
      messageValue: '',
      loading: false,
      grammarChecked: false,
      grammarCheckedValue: '',
      systemValue: '你是一名知识丰富的DBA',
      checkList: [],
      recordKey: null,
      keywordList: [],
      previewTipsDialog: false,
      previewErrorTipsDialog: false,
      errorMessage: '',
      bottomHidden: false,
      previewErrorStackTipsDialog: false,
      errorStackMessage: '',
      contrastDdl: {},
      sinkKey: null,
      aiModelList: [],
      aiModel: 'Doubao-lite-32k'

    }
  },
  created() {
    window.addEventListener('resize', this.calculateInputHeight)
    this.contrastDdl.sinkDdl =
      JSON.parse(localStorage.getItem('migrationReportAi')).sinkDdl || ''
    this.contrastDdl.sourceDdl =
      JSON.parse(localStorage.getItem('migrationReportAi')).sourceDdl || ''
    this.errorMessage = JSON.parse(
      localStorage.getItem('migrationReportAi')
    ).message
    this.errorStackMessage = JSON.parse(
      localStorage.getItem('migrationReportAi')
    ).errors
  },
  async mounted() {
    const res = await getAiList()
    Object.keys(this.sort(res)).forEach((f) => {
      this.aiModelList.push({
        label: `${res[f]}(${f})`,
        value: f
      })
    })
    this.getKeyword()
  },
  methods: {
    sort(data) {
      const sortedData = Object.entries(data).sort((a, b) => {
        const [, valueA] = a
        const [, valueB] = b
        return valueA.split('-')[0].localeCompare(valueB.split('-')[0])
      })
      const result = Object.fromEntries(sortedData)
      return result
    },
    async handleSuccess() {
      const { id, taskId, jobId } = JSON.parse(
        localStorage.getItem('migrationReportAi')
      )
      const res = await dataReportObjectEdit({
        id,
        code: 2,
        sinkDdl: this.contrastDdl.sinkDdl
      })
      this.$message.success(res.msg)
      setTimeout(() => {
        this.$router.push({
          path: '/report/migrationReport',
          query: {
            taskId,
            jobId
          }
        })
      }, 1500)
    },
    applySink(ddl) {
      this.contrastDdl.sinkDdl = ddl
      this.$emit('setSinkDdl', ddl)
    },
    async handleSqlTask() {
      const {
        taskType,
        sinkId
      } = this.$props.databaseInfo
      const res = await sqlTaskExecuteSql({
        databaseName: taskType.split('-')[1],
        datasourceId: sinkId,
        sqlContext: this.$props.sinkDdl
      })
      if (res.data.code === 500) {
        this.executeErrorMessage = res.data.msg
      }
      this.$message[res.data.code === 500 ? 'error' : 'success'](res.data.msg)
    },
    async convertSql() {
      // eslint-disable-next-line no-unused-vars
      const res = await convertSqlPush({
        id: '1',
        name: '1',
        title: '1',
        convertType: '1',
        sourceType: 'MySql'
      })
    },
    async getKeyword() {
      const { taskId, type } = JSON.parse(
        localStorage.getItem('migrationReportAi')
      )
      const res = await getKeyword({
        taskId,
        objectType: type
      })
      this.keywordList = []
      res.data.forEach((f, i) => {
        if (i !== 0) {
          this.keywordList.push(f)
        }
      })
    },
    handleCheckbox(_v) {
      if (_v) {
        this.grammarCheckedValue =
          this.dict.type.grammar_compatible_conversion[0].value
      } else {
        this.grammarCheckedValue = null
      }
    },
    handleInputMessage(e) {
      const inputElement = this.$refs.inputRef
      if (inputElement === null) {
        return
      }
      this.$nextTick(() => {
        const computedInputStyle = window.getComputedStyle(inputElement)
        const maxHeightString =
          computedInputStyle.getPropertyValue('max-height')
        const maxHeight = parseInt(maxHeightString)
        inputElement.setAttribute('style', `height: auto; overflow-y: hidden;`)
        inputElement.setAttribute(
          'style',
          `height: ${inputElement.scrollHeight}px; ${
            inputElement.scrollHeight > maxHeight
              ? `overflow-y: auto;`
              : 'overflow-y: hidden;'
          }`
        )
      })
    },
    handleKeydown(event) {
      this.handleInputMessage()
      if (event.key === 'Enter' && !event.shiftKey) {
        event.preventDefault()

        this.handleSendMessage()
      }
    },
    scrollToBottom() {
      this.$nextTick(() => {
        const scrollElem = this.$refs.messageBox
        scrollElem.scrollTo({
          top: scrollElem.scrollHeight,
          behavior: 'smooth'
        })
      })
    },
    getLogoUrl() {
      const logoMap = {
        ERNIE: wenxin,
        gpt: chatgpt,
        Doubao: doubao,
        qwen: tongyi,
        GLM: zhipu
      }

      for (const key in logoMap) {
        if (this.aiModel.includes(key)) {
          return logoMap[key]
        }
      }

      return false
    },
    async handleSendMessage() {
      const that = this
      // console.log(this.messageValue);
      if (
        this.messageValue.replace(/[\r\n\s]/g, '').length < 1 ||
        this.loading
      ) {
        return
      }
      this.loading = true
      const value = this.getMessageValue()
      this.messageValue = ''
      this.handleInputMessage()
      this.historyMessage.push({
        type: 'user',
        message: value
      })
      this.scrollToBottom()
      const res = await sendAiMessage({
        model: this.aiModel,
        stream: true,
        messages: that.getMessage()
      })
      if (res.error) {
        this.historyMessage.push({
          type: 'error',
          message: res.error.message,
          logo: this.getLogoUrl()
        })
        this.loading = false
        return
      }
      that.historyMessage.push({
        type: 'success',
        message: '',
        logo: that.getLogoUrl()
      })
      const reader = res.getReader()
      const decoder = new TextDecoder('utf-8')
      this.loading = false
      let buffer = ''
      function readStream() {
        reader.read().then(({ done, value }) => {
          if (done) {
            if (
              that.historyMessage[that.historyMessage.length - 1].message
                .length === 0
            ) {
              that.historyMessage[that.historyMessage.length - 1] = {
                type: 'error',
                message: '次数不足，请切换AI源~~',
                logo: that.getLogoUrl()
              }
              that.recordKey = Math.random()
            }
            that.$emit('getHistory-event', that.historyMessage)
            console.log('读取流结束')
            return
          }
          buffer += decoder.decode(value, { stream: true })
          const events = buffer
            .split('\n\n')
            .filter((event) => event.trim() !== '')
          const remaining = buffer.slice(buffer.lastIndexOf('\n\n') + 2)
          events.forEach((event) => {
            const lines = event.split('\n')
            const eventData = {}
            lines.forEach((line) => {
              const [key, ...values] = line.split(': ')
              eventData[key] = values.join(': ')
            })
            if (eventData.data) {
              try {
                const jsonEvent = JSON.parse(eventData.data)
                that.historyMessage[that.historyMessage.length - 1].message +=
                  jsonEvent.choices[0].delta.content || ''
                that.scrollToBottom()
              } catch (error) {
                return
              }
            }
          })

          buffer = remaining
          readStream()
        })
      }
      readStream()
    },
    getMessageValue() {
      const { sourceDdl, sinkDdl } = this.contrastDdl
      const lengthBool = this.messageValue.length > 0
      const { taskType } = this.$props.databaseInfo
      let basic = `请将以下${taskType.split('-')[0]}的创建存储过程的SQL换为${
        this.grammarCheckedValue || taskType.split('-')[1]
      }的创建${this.$props.taskType}的SQL： \n ' ${
        sinkDdl || sourceDdl
      } ' \n 错误信息为：\n ${this.executeErrorMessage || this.errorMessage} \n转换要求：`
      basic += lengthBool ? `\n 1.${this.messageValue}` : ''
      this.checkList.forEach((f, i) => {
        f = f.replace(/\n/g, '')
        basic += `\n ${length ? i + 2 : i + 1}.${f} `
      })
      return basic
    },
    getMessage() {
      const arr = []
      this.historyMessage.forEach((f, i) => {
        arr.push({
          role: i % 2 === 0 ? 'user' : 'system',
          content: f.message
        })
      })
      arr.unshift({
        role: 'system',
        content: this.systemValue
      })
      return arr
    }
  }
}
</script>

<style lang="scss" scoped>
.chatBox {
  width: 100%;
  height: 100%;
  overflow: auto;

  .label {
    font-weight: 600;
    color: #000;
    font-size: 14px;
    margin: 0;
    margin-right: 10px;
    .changeTips {
      float: right;
      font-weight: 500;
      color: #555;
      font-size: 12px;
      cursor: pointer;
    }
  }

  .tips {
    width: 100%;
    margin: 0.5rem auto;

    .tips-item {
      margin: 10px 0 0 25px;
    }
  }

  .grammar {
    width: 100%;
    margin: 0.5rem auto;
    height: 30px;

    .a {
      color: rgb(68, 68, 255);
      float: right;
      cursor: pointer;
      font-size: 12px;
    }
  }

  .chat {
    width: 100%;
    height: 67%;
    border-radius: 5px;
    margin: 0.5rem auto;
    box-shadow: 0 0 5px #ccc;
    background-color: #fff;

    ul {
      list-style-type: none;
      padding: 0;
      margin: 0;
    }
  }
  .bottomHidden {
    height: 0 !important;
    overflow: hidden;
    transition: all 0.3s linear;
  }

  .top_display {
    position: fixed;
    bottom: 5px;
    border-top-left-radius: 15px;
    border-top-right-radius: 15px;
    background: #1f2937;
    width: 35px;
    height: 20px;
    text-align: center;
    left: calc(50% - 17.5px);
    transition-delay: 0.3s;
    display: block !important;

    svg {
      cursor: pointer;
      transform: translateY(-2px);
    }

    &:hover {
      svg {
        animation: top 0.8s linear infinite;
      }

      @keyframes top {
        0% {
          transform: translateY(-5px);
        }
        100% {
          transform: translateY(-2px);
        }
      }
    }
  }

  .fn_bottom {
    transition: all 0.5s ease;
    width: 500px;
    height: 60px;
    margin: 10px auto;
    position: fixed;
    z-index: 2;
    background-color: #1f2937;
    color: #fff;
    box-shadow: 1px 0px 10px 0px #ddd;
    bottom: 10px;
    border-radius: 30px;
    left: calc(50% - 250px);
    .svg {
      background: #1f2937;
      width: 30px;
      height: 15px;
      display: inline-block;
      position: absolute;
      bottom: -15px;
      left: calc(50% - 15px);
      text-align: center;
      border-bottom-left-radius: 15px;
      border-bottom-right-radius: 15px;

      &:hover {
        svg {
          animation: bottom 0.8s linear infinite;
        }
      }

      svg {
        cursor: pointer;
        transform: translateY(-9px);
      }

      @keyframes bottom {
        0% {
          transform: translateY(-7px);
        }
        100% {
          transform: translateY(-9px);
        }
      }
    }

    .fn_bottom-main {
      display: flex;
      height: 100%;
      align-items: center;
      justify-content: space-around;
      .fn_bottom-main-item {
        margin: 0 15px;
        display: flex;
        flex-wrap: wrap;
        flex-direction: column;
        align-items: center;
        cursor: pointer;
        &:hover {
          transform: scale(1.1);
        }

        p {
          font-size: 13px;
          margin: 0;
        }
      }
    }
  }
}

.contrastBox {
  display: flex;
  align-items: center;
  justify-content: space-between;

  .Divider {
    height: 450px;
    width: 2px;
    border: 2px dashed #595959;
  }
}
</style>

<style scoped>
.user {
  text-align: right;
}

.user > div {
  text-align: left;
  word-break: break-word;
  white-space: pre-wrap;
  border-radius: 15px;
  padding: 5px 10px;
  font-size: 14px;
  display: inline-block;
  width: auto;
  color: #121512;
  background-color: rgb(245, 245, 245);
}

p {
  font: 400 16px / 24px Inter, -apple-system, BlinkMacSystemFont, Segoe UI,
    SF Pro SC, SF Pro Display, SF Pro Icons, PingFang SC, Hiragino Sans GB,
    Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif;
}

.chartBox {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

.chartBox {
  display: flex;
}

.left {
  width: 25%;
  background-color: rgb(244, 244, 244);
  height: 100%;
  border-top-right-radius: 10px;
  border-bottom-right-radius: 10px;
  padding-top: 20px;
}

.left > .chart-select {
  padding: 0 5px;
  width: 80%;
  height: 50px;
  margin: 30px auto;
  border: 1px solid rgb(192, 196, 204);
}

.send-btn-fDrkYV svg {
  transition: color 0.2s linear;
}

.right {
  width: 100%;
  height: 100%;
  /* text-align: center; */
  overflow: auto;
  position: relative;
  background-color: #fff;
}

.info {
  position: absolute;
  bottom: 0;
}

.oner {
  height: 100%;
  padding: 15px;
  overflow: auto;
}

.chat-input-container {
  border: 1px solid rgb(229, 229, 229);
  background: #fff;
  border-radius: 5px;
  box-shadow: 0 6px 10px 0 rgba(42, 60, 79, 0.1);
  box-sizing: border-box;
  width: 100%;
  margin: 0 auto;
}

.grid-container {
  align-items: flex-end;
  display: grid;
  gap: 10px;
  grid-template-areas: "left-tools input-area right-tools";
  grid-template-columns: auto 1fr auto;
  grid-template-rows: auto;
  width: 100%;
}

.chat-input {
  background: #fff;
  border-radius: 220px;
  box-sizing: border-box;
  display: flex;
  width: 100%;
  padding: 5px 12px 5px 14px;
  position: relative;
}

.grid-container .grid-input-area {
  align-self: center;
  width: 100%;
  grid-area: input-area;
  display: flex;
  align-items: center;
}

.chat-input .input {
  background-color: transparent !important;
}

.chat-input .input {
  align-self: center;
  border-radius: 0 !important;
  border-width: 0 !important;
  caret-color: #0057ff;
  caret-color: #0057ff;
  flex: 1 1 !important;
  min-width: 0 !important;
  overflow-x: hidden !important;
  padding: 0 !important;
  width: 100% !important;
}

.container-AilALM.flow-xs54Ev.semi-input-textarea-wrapper .semi-input-textarea {
  border-radius: 12px;
  cursor: auto;
  font: 400 16px / 24px Inter, -apple-system, BlinkMacSystemFont, Segoe UI,
    SF Pro SC, SF Pro Display, SF Pro Icons, PingFang SC, Hiragino Sans GB,
    Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif;
  overflow-anchor: auto;
  overflow-y: auto;
  padding: 0 12px;
}

.chat-input .input .semi-input-textarea {
  max-height: 180px !important;
  min-width: 0px !important;
  padding: 0 0 0 0 !important;
}

.chat-input .input textarea {
  border-radius: 0 !important;
  color: #000;
  color: var(--color-neutral-100, #000);
}

.semi-input-textarea {
  background-color: transparent;
  border: 0 solid transparent;
  box-shadow: none;
  box-sizing: border-box;
  color: rgb(28, 31, 35);
  cursor: text;
  font: 400 16px / 24px Inter, -apple-system, BlinkMacSystemFont, Segoe UI,
    SF Pro SC, SF Pro Display, SF Pro Icons, PingFang SC, Hiragino Sans GB,
    Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif;
  font-size: 14px;
  line-height: 20px;
  outline: none;
  padding: 5px 12px;
  position: relative;
  resize: none;
  vertical-align: bottom;
  width: 100%;
}

.send-btn-fDrkYV,
.send-btn-fDrkYV svg {
  height: 28px;
  width: 28px;
}
.send-btn-fDrkYV {
  background-color: #f5f5f5;
  border: 0;
  border-radius: 18px;
  box-sizing: border-box;
  padding: 0;
}

.semi-button {
  cursor: pointer;
}

.line {
  width: 1px;
  height: 20px;
  background: rgba(0, 0, 0, 0.2);
  margin: 0 10px;
}

.api {
  margin: 10px 0;
}

.message-success_content {
  display: flex;
  margin: 25px 0;
}

.aiLogo {
  width: 25px;
  border-radius: 20px;
}

.message-content {
  font: 400 16px / 24px Inter, -apple-system, BlinkMacSystemFont, Segoe UI,
    SF Pro SC, SF Pro Display, SF Pro Icons, PingFang SC, Hiragino Sans GB,
    Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif;
}

.errorTips {
  color: red;
  margin: 0 10px;
  float: right;
  cursor: pointer;
  font-size: 12px;
}

.errMessageTips {
  width: 100%;
  overflow: auto;
  background: #2a313d;
  color: #ccc;
  height: 100%;
  padding: 10px;
  font-size: 14px;
}
</style>
